package com.sound
{
	import com.utils.Print;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;

	/**
	 * 音乐管理器
	 * @author yangyang
	 *
	 */
	public class SoundManager
	{
		private static var instance : SoundManager;

		private var bgSound : SoundInst;

		public var bgSoundTransform : SoundTransform;
		public var effectSoundTransform : SoundTransform;

		private var soundDatas : Array = [];
		private var soundClassDatas : Dictionary = new Dictionary();
		public var musicClose : Boolean;
		public var soundClose : Boolean;

		public static function getInstance() : SoundManager
		{
			if(instance == null)
			{
				instance = new SoundManager();
			}
			return instance;
		}

		public function SoundManager()
		{
			bgSoundTransform = new SoundTransform();
			effectSoundTransform = new SoundTransform();
		}


		/**
		 * 播放一个音乐文件
		 * @param soundID
		 * @param loops
		 * @param soundTransform
		 * @return
		 */
		public function play(soundID : String, loops : int = 0, soundTransform : SoundTransform = null) : SoundInst
		{
			try
			{
				var sound : SoundInst = getSoundRes(soundID);

				if(sound == null)
				{
					var soundClass : Class = getSoundClass(soundID);
					sound = new SoundInst(soundClass, onSoundComplete);
					sound.name = soundID;
				}
				else
				{
					sound.pause();
				}

				var soundChannel : SoundChannel = sound.play(0, loops, soundTransform);

				//保持引用，防止被回收
				if(soundChannel)
				{
					soundDatas.push(sound);
				}
				else
				{
					trace("无法播放该声音文");
				}
			}
			catch(e : Error)
			{
				Print.error("播放音乐失败", soundID);
			}

			return sound;
		}

		public function addSoundClass(soundID : String, resClass : Class) : void
		{
			soundClassDatas[soundID] = resClass;
		}

		public function getSoundClass(soundID : String) : Class
		{
			if(soundClassDatas[soundID] == null)
			{
				var resClass : Class = ApplicationDomain.currentDomain.getDefinition(soundID) as Class;

				if(resClass)
				{
					addSoundClass(soundID, resClass);
				}
			}
			return soundClassDatas[soundID];
		}

		public function getSoundRes(soundID : String) : SoundInst
		{
			for each(var sound : SoundInst in soundDatas)
			{
				if(sound.name == soundID)
				{
					return sound;
				}
			}
			return null;
		}

		/**
		 * 声音播放完毕后消除引用
		 * 如果是背景音乐的话则重复播放
		 * @param sound
		 *
		 */
		private function onSoundComplete(sound : SoundInst) : void
		{
			if(sound == bgSound)
			{
				bgSound.restart();
				return;
			}
			
			// 在战半内一定要缓存音效实例，不然每次特效和敲击音效整局战斗下来创建内存过多
		/*	var index : int = soundDatas.indexOf(sound);

			if(index != -1)
			{
				soundDatas.splice(index, 1);
			}*/
		}

		/**
		 * 暂停播放一个音乐文件
		 * @param soundID
		 */
		public function pause(soundID : String) : void
		{
			var sound : SoundInst = getSoundRes(soundID);
			
			if(sound)
			{
				sound.pause();
			}
		}

		/**
		 * 恢复一个音乐文件的播放，如果没有被暂停过，则直接播放
		 * @param soundID
		 */
		public function resume(soundID : String) : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				if(sound.name == soundID)
					sound.resume();
			}
		}

		/**
		 * 释放一个音乐文件  ，关闭音乐文件 正在加载的数据流并停止播放；
		 * 注： 在下次重新播放该音乐文件 时将会重新加载数据流
		 */
		public function dispose(soundID : String) : void
		{
			for(var i : int = 0; i < soundDatas.length; i++)
			{
				var sound : SoundInst = soundDatas[i];

				if(sound.name == soundID)
				{
					sound.dispose();
					soundDatas.splice(i, 1);
				}
			}
		}

		/**
		 * 播放所有
		 */
		public function playAll() : void
		{
			resumeAll();
		}

		/**
		 * 暂停所有播放
		 */
		public function pauseAll() : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				sound.pause();
			}
		}

		/**
		 * 恢复所有播放
		 */
		public function resumeAll() : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				sound.resume();
			}
		}

		/**
		 * 关闭所有
		 */
		public function disposeAll() : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				sound.dispose();
			}
			bgSound = null;
			soundDatas.length = 0;
		}

		private var _bgSoundIndex : int = 0;

		/**
		 * 播放背景音乐
		 * 如果是关闭背景音乐状态，则暂停播放。
		 * @param soundID
		 */
		public var _currentBgId : String;

		public function playBgSound(soundID : String, loops : int = 0) : void
		{
			if(_currentBgId == soundID)
				return;


			if(bgSound)
				bgSound.pause();
			bgSound = play(soundID, loops, bgSoundTransform);
			
			if(bgSound && musicClose)
			{
				bgSound.pause();
			}
			_currentBgId = soundID;
		}

		/**
		 * 暂停背景音乐
		 *
		 */
		public function pauseBgSound() : void
		{
			if(bgSound)
				bgSound.pause();
			_currentBgId = "";
		}

		/**
		 * 播放特效音乐
		 * @param soundID
		 * @param loops
		 *
		 */
		public function playEffectSound(soundID : String, loops : int = 1) : void
		{
			if(soundClose)
				return;
			play(soundID, loops, effectSoundTransform);
		}

		/**
		 * 暂停所有特效音乐
		 *
		 */
		public function pauseEffectSound() : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				if(sound != bgSound)
					sound.pause();
			}
		}

		/**
		 * 恢复播放特效音乐
		 *
		 */
		public function resumeEffectSound() : void
		{
			for each(var sound : SoundInst in soundDatas)
			{
				if(sound != bgSound)
					sound.resume();
			}
		}

		/**
		 * 设置背景音乐的音量
		 * @param vol
		 * @param panning
		 * @param leftToLeft
		 * @param leftToRight
		 * @param rightToLeft
		 * @param rightToRight
		 *
		 */
		public function setBgSoundTransform(vol : Number, panning : Number = 0, leftToLeft : Number = 1, leftToRight : Number = 1, rightToLeft : Number = 1, rightToRight : Number = 1) : void
		{
			bgSoundTransform.volume = vol;
			bgSoundTransform.pan = panning;
			bgSoundTransform.leftToLeft = leftToLeft;
			bgSoundTransform.leftToRight = leftToRight;
			bgSoundTransform.rightToLeft = rightToLeft;
			bgSoundTransform.rightToRight = rightToRight;

			if(bgSound)
				bgSound.setSoundTransform(bgSoundTransform);
		}

		/**
		 * 设置特效音乐的音量
		 * @param vol
		 * @param panning
		 * @param leftToLeft
		 * @param leftToRight
		 * @param rightToLeft
		 * @param rightToRight
		 *
		 */
		public function setEffectSoundTransform(vol : Number, panning : Number = 0, leftToLeft : Number = 1, leftToRight : Number = 1, rightToLeft : Number = 1, rightToRight : Number = 1) : void
		{
			effectSoundTransform.volume = vol;
			effectSoundTransform.pan = panning;
			effectSoundTransform.leftToLeft = leftToLeft;
			effectSoundTransform.leftToRight = leftToRight;
			effectSoundTransform.rightToLeft = rightToLeft;
			effectSoundTransform.rightToRight = rightToRight;
		}
	}
}